Skip to content

refactor(cli): parse JS command arguments with clap - #2523

Merged
fengmk2 merged 20 commits into
mainfrom
rfc/napi-clap-cli-args
Aug 29, 2026
Merged

refactor(cli): parse JS command arguments with clap#2523
fengmk2 merged 20 commits into
mainfrom
rfc/napi-clap-cli-args

Conversation

@fengmk2

@fengmk2 fengmk2 commented Aug 21, 2026

Copy link
Copy Markdown
Member

Move argument parsing for the staged, config, hooks, migrate, and create commands from JavaScript to Rust. Each NAPI parser uses clap for strict validation and returns a typed result to JavaScript.

Call graph

process.argv
    |
    v
local Node.js CLI
packages/cli/src/bin.ts
    |
    | raw arguments for one JavaScript command
    v
NAPI parser function
packages/cli/binding/src/js_command_args/
    |
    v
clap command grammar
    |
    +-- checks aliases and option boundaries
    +-- converts values
    +-- checks explicit negation
    +-- rejects unknown options
    +-- rejects invalid positional arguments
    |
    v
validated Rust arguments
    |
    v
typed NAPI parse outcome
    |
    v
JavaScript command operations

JavaScript sends raw arguments to one NAPI parser. JavaScript does not parse the returned values again.

The Rust parsers print command help through the shared vp_cli_help formatter. The global and local CLI paths use the same help format. The create parser keeps all template arguments after the separator in their original order.

This change removes duplicate JavaScript option data and the direct mri dependency. The RFC defines the parser rules, help synchronization, NAPI result types, and command ownership.

Compatibility

Argument parsing is now strict. The CLI rejects unknown options and extra positional arguments. It rejects unsupported negative string options and repeated scalar options.

The staged command rejects invalid concurrency values. It also rejects empty --cwd, --diff, and --diff-filter values before JavaScript runs.

The create command rejects --all and invalid package-manager values. These inputs could pass through mri or fail later in JavaScript.

Performance

The benchmark compares the base commit 45acff9b4 with this branch. It ran on macOS ARM64 with Node.js 22.22.0.

Each CLI result used 25 to 30 alternating paired runs after four warm-up pairs. A negative change is faster.

The parser-only test used vp staged --allow-empty --concurrent=2 --diff-filter ACMR --no-stash.

Case Base mean PR mean Change
Staged parser only 1.20 µs 6.33 µs +5.13 µs
vp --version control 133.2 ms 133.4 ms +0.2 ms
vp staged --help 136.1 ms 133.9 ms -2.2 ms
vp config --help 149.4 ms 144.7 ms -4.7 ms
vp hooks --help 134.4 ms 132.9 ms -1.5 ms
vp migrate --help 155.8 ms 150.0 ms -5.8 ms
vp create --help 154.5 ms 150.1 ms -4.5 ms
vp staged --cwd 135.2 ms 134.5 ms -0.7 ms
vp hooks unknown 131.7 ms 132.0 ms +0.3 ms
vp config --hooks-dir 165.3 ms 144.6 ms -20.7 ms

The clap/NAPI parser is 5.3 times slower in isolation. This adds about 5 µs to a CLI process that takes 130 to 155 ms.

The CLI calls the parser one time. The complete CLI path has no measurable regression. Help is 1% to 4% faster.

vp config --hooks-dir is not a parser-only comparison. The base command starts hooks validation. The PR rejects the missing value first.

Unknown-option timings are not comparable. The base parser can accept an unknown option and start command work. The PR rejects it during parsing.

@netlify

netlify Bot commented Aug 21, 2026

Copy link
Copy Markdown

Deploy Preview for viteplus-preview ready!

Name Link
🔨 Latest commit fd33292
🔍 Latest deploy log https://app.netlify.com/projects/viteplus-preview/deploys/6a92f94f601b7b0008ede93d
😎 Deploy Preview https://deploy-preview-2523--viteplus-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@fengmk2 fengmk2 self-assigned this Aug 21, 2026
@fengmk2
fengmk2 force-pushed the rfc/napi-clap-cli-args branch from c616858 to 86300af Compare August 21, 2026 13:01
@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

CLI artifact sizes (fd33292)

Final release artifacts built by the canonical build-upstream and build-windows-cli actions.
The dist rows use the Linux build. The core total excludes .node files to match the release artifact.

Artifact Format Base PR Change
packages/cli/dist Directory total 1.61 MiB 1.59 MiB -18.84 KiB (-1.14%)
packages/core/dist Directory total 3.91 MiB 3.91 MiB 0 B (0.00%)
Combined package dist Directory total 5.52 MiB 5.50 MiB -18.84 KiB (-0.33%)
vp (Linux x64) Binary 10.73 MiB 10.74 MiB +12.00 KiB (+0.11%)
vp (Linux x64) gzip -9 4.64 MiB 4.64 MiB +5.23 KiB (+0.11%)
NAPI (Linux x64) Binary 32.20 MiB 32.39 MiB +196.00 KiB (+0.59%)
NAPI (Linux x64) gzip -9 12.69 MiB 12.76 MiB +70.03 KiB (+0.54%)
vp (macOS ARM64) Binary 8.02 MiB 8.03 MiB +16.16 KiB (+0.20%)
vp (macOS ARM64) gzip -9 4.05 MiB 4.05 MiB +3.74 KiB (+0.09%)
NAPI (macOS ARM64) Binary 39.79 MiB 39.93 MiB +145.27 KiB (+0.36%)
NAPI (macOS ARM64) gzip -9 16.98 MiB 17.05 MiB +66.18 KiB (+0.38%)
vp (Windows x64) Binary 8.63 MiB 8.63 MiB +7.50 KiB (+0.08%)
vp (Windows x64) gzip -9 3.76 MiB 3.77 MiB +6.57 KiB (+0.17%)
NAPI (Windows x64) Binary 27.03 MiB 27.20 MiB +172.50 KiB (+0.62%)
NAPI (Windows x64) gzip -9 10.76 MiB 10.82 MiB +65.98 KiB (+0.60%)
Trampoline (Windows x64) Binary 14.00 KiB 14.00 KiB 0 B (0.00%)
Trampoline (Windows x64) gzip -9 7.09 KiB 7.09 KiB 0 B (0.00%)
Installer (Windows x64) Binary 4.50 MiB 4.50 MiB 0 B (0.00%)
Installer (Windows x64) gzip -9 2.11 MiB 2.11 MiB 0 B (0.00%)

@fengmk2
fengmk2 force-pushed the rfc/napi-clap-cli-args branch 3 times, most recently from 7753568 to 6ea10b8 Compare August 23, 2026 05:28
@fengmk2 fengmk2 added test: e2e Auto run e2e tests test: create-e2e Run `vp create` e2e tests labels Aug 23, 2026
Comment thread rfcs/napi-clap-cli-args.md Outdated
@fengmk2
fengmk2 force-pushed the rfc/napi-clap-cli-args branch from 6ea10b8 to 61729ba Compare August 23, 2026 12:41
@fengmk2

fengmk2 commented Aug 25, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: 67ab1181e1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@fengmk2
fengmk2 marked this pull request as ready for review August 25, 2026 13:00
@fengmk2 fengmk2 added test: install-e2e run vite install e2e test test: sfw preview-build Publish this PR's commits to the registry bridge as preview builds labels Aug 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Registry bridge build (fd33292)

This commit build is published to the registry bridge, which serves these as ordinary npm versions (every other package proxies to npmjs):

Package Version
vite-plus 0.0.0-commit.fd332923578a5349f99ca6441856b6c80d94f058
@voidzero-dev/vite-plus-core 0.0.0-commit.fd332923578a5349f99ca6441856b6c80d94f058

Install the Vite+ CLI built from this commit, then migrate a project:

# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/voidzero-dev/vite-plus/fd332923578a5349f99ca6441856b6c80d94f058/packages/cli/install.sh | VP_PR_VERSION=2523 bash
# Windows (PowerShell)
$env:VP_PR_VERSION="2523"; irm https://raw.githubusercontent.com/voidzero-dev/vite-plus/fd332923578a5349f99ca6441856b6c80d94f058/packages/cli/install.ps1 | iex

Or download the standalone Windows installer built from this commit:

Architecture Installer
x64 vp-setup-x86_64-pc-windows-msvc.exe
Arm64 vp-setup-aarch64-pc-windows-msvc.exe

GitHub requires you to sign in and downloads each installer as a ZIP artifact. Extract vp-setup.exe, then run it against this preview build:

.\vp-setup.exe --version "0.0.0-commit.fd332923578a5349f99ca6441856b6c80d94f058" --registry "https://registry-bridge.viteplus.dev/"

After installing, upgrade the current project's vite-plus to this test build with:

vp migrate

Or point your package manager at the bridge registry https://registry-bridge.viteplus.dev/:

Package manager Registry config
npm / pnpm / Bun .npmrc: registry=https://registry-bridge.viteplus.dev/
Yarn (v2+) .yarnrc.yml: npmRegistryServer: "https://registry-bridge.viteplus.dev/"

Then pin the build (vite aliases to vite-plus-core; pnpm can use a catalog, npm an overrides entry):

{
  "devDependencies": {
    "vite-plus": "0.0.0-commit.fd332923578a5349f99ca6441856b6c80d94f058",
    "vite": "npm:@voidzero-dev/vite-plus-core@0.0.0-commit.fd332923578a5349f99ca6441856b6c80d94f058"
  }
}

@fengmk2
fengmk2 merged commit 3380eb8 into main Aug 29, 2026
163 of 182 checks passed
@fengmk2
fengmk2 deleted the rfc/napi-clap-cli-args branch August 29, 2026 15:53
@github-actions

Copy link
Copy Markdown
Contributor

🐳 Docker preview image

Built from this PR's registry bridge build:

Image Compressed size
ghcr.io/voidzero-dev/vite-plus:pr-2523 236MB
# remove any stale local copy from a previous run, then pull fresh
docker rmi ghcr.io/voidzero-dev/vite-plus:pr-2523 2>/dev/null; docker pull ghcr.io/voidzero-dev/vite-plus:pr-2523

Quick check:

docker run --rm ghcr.io/voidzero-dev/vite-plus:pr-2523 vp --version

See docs/guide/docker.md for usage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

preview-build Publish this PR's commits to the registry bridge as preview builds test: create-e2e Run `vp create` e2e tests test: e2e Auto run e2e tests test: install-e2e run vite install e2e test test: sfw

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants